<?php


namespace App\Services;


use App\Imports\CustomerImport;
use App\Models\Customer;
use App\Models\CustomerRecords;
use App\Models\CustomerRecordsFile;
use App\Models\User;
use App\Service\Service;
use Carbon\Carbon;
use Dingo\Api\Http\Request;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Schema\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
 * Class CustomerService
 * @property integer $to_user_id
 * @property array $selectKeys
 * @property string $contact_name
 * @property string $contact_mobile
 * @property string $company_name
 * @property string $wechat
 * @property integer $from
 * @property integer $level
 * @property integer $province
 * @property integer $city
 * @property integer $district
 * @property string $address
 * @property integer $status
 * @property string $remark
 * @property integer $follow_id
 * @property string $keywords
 * @property integer $customer_id
 * @property integer $type
 * @property integer $result
 * @property array $files
 * @property boolean $assigned
 * @property boolean $sea
 * @package App\Services
 * @author thanatos thanatos915@163.com
 */
class CustomerService extends Service
{

    /**
     * 客户列表
     * @param Request $request
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     * @author thanatos thanatos915@163.com
     */
    public static function search(Request $request)
    {
        $service = static::loadParams($request, [
            'follow_id' => 'numeric',
            'keywords' => 'string',
            'level' => 'numeric',
            'from' => 'numeric',
            'sea' => 'boolean'
        ]);

        $query = Customer::with(['createdUser', 'followUser'])->where('in_sea', $service->sea)->orderBy('id', 'desc');


        // TODO 验证客户查询权限
        if ($service->keywords) {
            $query->where(function (/** @var \Illuminate\Database\Eloquent\Builder $query */ $query) use ($service) {
                $like = '%' . $service->keywords . '%';
                $query->where('contact_name', 'like', $like)
                    ->orWhere('contact_mobile', 'like', $like)
                    ->orWhere('company_name', 'like', $like);
            });
        }

        if ($service->level) {
            $query->where('level', $service->level);
        }

        if ($service->from) {
            $query->where('from', $service->from);
        }

        if ($service->status) {
            $query->where('status', $service->status);
        }

        return $query->paginate();
    }

    public static function info($id)
    {
        /** @var Customer $model */
        $model = Customer::with(['createdUser', 'followUser', 'provinceData', 'cityData', 'districtData'])->find($id);

        if (empty($model)) {
            throw new BadRequestHttpException("客户不存在");
        }
        if (!in_array(get_user_id(), [$model->create_id, $model->follow_id])) {
            throw new BadRequestHttpException("没有权限编辑");
        }

        return $model;
    }

    /**
     * 创建或保存客户
     * @param Request $request
     * @param int $id
     * @return Customer|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model
     * @author thanatos thanatos915@163.com
     */
    public static function createAndUpdate(Request $request, $id = 0)
    {
        $service = static::loadParams($request, [
            'contact_name' => 'required|string',
            'contact_mobile' => 'required|string',
            'company_name' => 'required|string',
            'wechat' => 'string',
            'from' => 'required',
            'level' => 'numeric',
            'province' => 'numeric',
            'city' => 'numeric',
            'district' => 'numeric',
            'address' => 'string',
            'status' => 'numeric',
            'remark' => 'required|string'
        ]);

        if (Customer::whereContactMobile($service->contact_mobile)->where('id', '<>', $id)->exists()) {
            throw new BadRequestHttpException("客户联系方式已存在，无法添加");
        }

        if ($id > 0) {
            $model = Customer::find($id);
        }
        if (empty($model)) {
            $model = new Customer();
        }
        $model->create_id = get_user_id();
        $model->follow_id = get_user_id();
        if ($model->wechat) {
            $model->add_wechat_at = Carbon::now();
        }
        $model->assigned = true;

        $model->fill($service->getAttributes());
        $model->save();
        return $model;
    }

    /**
     * 客户转移
     * @param Request $request
     * @author thanatos thanatos915@163.com
     */
    public static function move(Request $request)
    {
        $service = self::loadParams($request, [
            'customer_id' => 'required|numeric',
            'to_user_id' => 'required|numeric'
        ]);

        $custom = Customer::find($service->customer_id);
        if (empty($custom)) {
            throw new BadRequestHttpException("客户不存在");
        }

        if (!isAdmin() && $custom->follow_id != get_user_id()) {
            throw new BadRequestHttpException("不能转移别人的客户");
        }

        $user = User::find($service->to_user_id);
        if (empty($user)) {
            throw new BadRequestHttpException("目标用户不存在");
        }

        $custom->follow_id = $user->id;
        $custom->save();
    }

    /**
     * 客户跟进
     * @param Request $request
     * @author thanatos thanatos915@163.com
     */
    public static function follow(Request $request)
    {
        $service = static::loadParams($request, [
            'customer_id' => 'required|numeric',
            'type' => [
                'required',
                Rule::in(CustomerRecords::$TYPES)
            ],
            'result' => [
                'required',
                Rule::in(CustomerRecords::$RESULTS)
            ],
            'remark' => 'required',
            'files' => 'array',
        ]);

        $customer = Customer::find($service->customer_id);
        if (empty($customer)) {
            throw new BadRequestHttpException("客户不存在");
        }

        if ($customer->follow_id != get_user_id()) {
            throw new BadRequestHttpException("不能跟踪不属于自己的用户");
        }

        DB::transaction(function () use($service) {
            $record = CustomerRecords::create([
                'user_id' => get_user_id(),
                'customer_id' => $service->customer_id,
                'type' => $service->type,
                'result' => $service->result,
                'remark' => $service->remark,
            ]);

            if (empty($record)) {
                throw new BadRequestHttpException("跟踪记录创建失败");
            }

            $files = [];
            foreach ($service->files as $item) {
                array_push($files, [
                    'records_id' => $record->id,
                    'path' => $item,
                ]);
            }
            CustomerRecordsFile::insert($files);
        });
    }

    /**
     * 获取跟进记录列表
     * @param Request $request
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     * @author thanatos thanatos915@163.com
     */
    public static function records(Request $request)
    {
        $service = static::loadParams($request, [
            'customer_id' => 'required|numeric'
        ]);

        $query = CustomerRecords::with(['user', 'files'])->whereCustomerId($service->customer_id)->orderBy('created_at', 'desc');

        return $query->paginate();
    }

    /**
     * 客户批量导入
     * @param Request $request
     * @author thanatos thanatos915@163.com
     */
    public static function import(Request $request)
    {
        $file = $request->input('file');
        $disk = Storage::disk('oss');
        if (!$disk->exists($file)) {
            throw new BadRequestHttpException("文件不存在");
        }
        Excel::import(new CustomerImport(), $file, 'oss');
    }

    /**
     * 客户分配列表
     * @param Request $request
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     * @author thanatos thanatos915@163.com
     */
    public static function importList(Request $request)
    {
        $service = static::loadParams($request, [
            'from' => 'numeric',
            'assigned' => 'numeric'
        ]);

        $query = Customer::with(['createdUser', 'followUser'])
            ->where('create_id', get_user_id())->orderBy('created_at', 'desc');

        if ($service->assigned) {
            $query->where('assigned', $service->assigned == 2);
        }

        return $query->paginate();
    }

    /**
     * 确认分配
     * @param Request $request
     * @author thanatos thanatos915@163.com
     */
    public static function confirmAssigned(Request $request)
    {
        $service = static::loadParams($request, [
            'selectKeys' => 'required|array'
        ]);

        /** @var Collection $customers */
        $customers = Customer::whereIn('id', $service->selectKeys)
            ->where('create_id', get_user_id())
            ->where('assigned', false)->get();

        $ids = $customers->modelKeys();

        Customer::whereIn('id', $ids)->update(['assigned' => true, 'assigned_at' => Carbon::now()]);
    }

    /**
     * 删除批量导入
     * @param Request $request
     * @author thanatos thanatos915@163.com
     */
    public static function assignedDelete(Request $request)
    {
        $service = static::loadParams($request, [
            'selectKeys' => 'required|array'
        ]);

        Customer::whereIn('id', $service->selectKeys)->delete();
    }

}
